// Copyright 2011-2012, Vanya Davidenko.
// Используемая кодировка: UTF-8.

#ifndef LIBV_BOOST_XML_XML_FILTER_NODE_ITERATOR_H_
#define LIBV_BOOST_XML_XML_FILTER_NODE_ITERATOR_H_

#include <iterator>
#include <boost/iterator/iterator_adaptor.hpp>



namespace libv {

// Реализован только forward-итератор, так как непонятно, как обозначать
// состоянии, когда при backward-поиске не найден элемент.
template<class TIterator, class TTagPred>
class FilterNodeIterator :
    public boost::iterator_adaptor<FilterNodeIterator<TIterator, TTagPred>,
                                   TIterator,
                                   boost::use_default,
                                   ::std::forward_iterator_tag> {
  friend class boost::iterator_core_access;
  public:
    FilterNodeIterator(const TIterator& i, const TTagPred& pred)
        : FilterNodeIterator::iterator_adaptor_(i),
          pred_(pred) {
        SatisfyPredicate();
    }

    bool AtEnd() const {
        return this->base().AtEnd();
    }

  private:
    void increment() {
        ++this->base_reference();
        SatisfyPredicate();
    }

    void SatisfyPredicate() {
        while ( !this->base().AtEnd() && !this->pred_(*this->base()) ) {
            ++(this->base_reference());
        }
    }

    TTagPred pred_;
};



template<class TIterator, class TTagPred>
FilterNodeIterator<TIterator, TTagPred>
MakeFilterNodeIterator(const TIterator& i, TTagPred pred) {
    return FilterNodeIterator<TIterator, TTagPred>(i, pred);
}

}  // libv

#endif  // LIBV_BOOST_XML_XML_FILTER_NODE_ITERATOR_H_
